package controller

import (
	"encoding/json"
	"fabric-go-sdk/sdk"
	"fabric-go-sdk/sdk/sdkInfo/chaincodeInfo"
	"github.com/gin-gonic/gin"
	"net/http"
)

// 用于处理资源管理客户端   链码生命周期

type CreatChaincodeForm struct {
	ChannelID string `json:"channel_id"`
	Name      string `json:"name"`
	Path      string `json:"path"`
}

// CreatChaincode 新建链码、打包链码
func CreatChaincode(c *gin.Context) {
	// 解析链码信息
	data, err := c.GetRawData()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "获取消息失败",
			"success": false,
		})
		return
	}
	form := &CreatChaincodeForm{}
	err = json.Unmarshal(data, form)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "序列化失败 err:" + err.Error(),
			"success": false,
		})
		return
	}
	// 创建链码实例
	ccInfoProject := chaincodeInfo.New(form.Name, form.Path)
	// 打包链码
	err = ccInfoProject.PackageCC()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "打包链码错误 err:" + err.Error(),
			"success": false,
		})
		return
	}
	// 将链码实例放到channel中
	_, ok := sdk.App.Channels[form.ChannelID]
	if !ok {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "通道" + form.ChannelID + "不存在",
			"success": false,
		})
		return
	}
	sdk.App.Channels[form.ChannelID].Chaincode[form.Name] = ccInfoProject
	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "成功",
		"success": true,
	})
	return
}

type InstallCCForm struct {
	ChannelId   string `json:"channel_id"`
	ChaincodeId string `json:"chaincode_id"`
	OrgName     string `json:"org_name"`
	PeerUrl     string `json:"peer_url"`
}

// InstallCC 安装链码
func InstallCC(c *gin.Context) {
	// 解析信息
	data, err := c.GetRawData()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "获取消息失败",
			"success": false,
		})
		return
	}
	form := &InstallCCForm{}
	err = json.Unmarshal(data, form)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "序列化失败 err:" + err.Error(),
			"success": false,
		})
		return
	}
	// 安装链码
	err = sdk.App.InstallCC(form.ChannelId, form.OrgName, form.ChaincodeId, form.PeerUrl)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "安装失败 err:" + err.Error(),
			"success": false,
		})
		return
	}
	// 返回安装成功响应
	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "安装成功",
		"success": true,
	})
	return
}

type ApproveCCForm struct {
	ChannelId   string `json:"channel_id"`
	OrgName     string `json:"org_name"`
	ChaincodeId string `json:"chaincode_id"`
}

// ApproveCC 批准链码
func ApproveCC(c *gin.Context) {
	// 解析信息
	data, err := c.GetRawData()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "获取消息失败",
			"success": false,
		})
		return
	}
	form := &ApproveCCForm{}
	err = json.Unmarshal(data, form)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "序列化失败 err:" + err.Error(),
			"success": false,
		})
		return
	}
	// 安装链码
	err = sdk.App.ApproveCC(form.ChannelId, form.OrgName, form.ChaincodeId)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "批准失败 err:" + err.Error(),
			"success": false,
		})
		return
	}
	// 返回安装成功响应
	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "批准成功",
		"success": true,
	})
	return
}

// CheckCCCommitReadiness 查询批准情况
func CheckCCCommitReadiness(c *gin.Context) {
	// 解析信息
	// 获取参数
	channelId := c.Query("channelId")
	orgName := c.Query("orgName")
	chaincodeId := c.Query("chaincodeId")
	// 查询
	res, err := sdk.App.CheckCCCommitReadiness(channelId, orgName, chaincodeId)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "查询失败 err:" + err.Error(),
			"success": false,
		})
		return
	}
	// 返回成功响应
	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "查询成功",
		"data":    res,
		"success": true,
	})
	return
}

type CommitCCForm struct {
	ChannelId   string `json:"channel_id"`
	OrgName     string `json:"org_name"`
	ChaincodeId string `json:"chaincode_id"`
}

// CommitCC 提交链码
func CommitCC(c *gin.Context) {
	// 解析信息
	data, err := c.GetRawData()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "获取消息失败",
			"success": false,
		})
		return
	}
	form := &CommitCCForm{}
	err = json.Unmarshal(data, form)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "序列化 err:" + err.Error(),
			"success": false,
		})
		return
	}
	// 提交链码
	err = sdk.App.CommitCC(form.ChannelId, form.OrgName, form.ChaincodeId)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "提交失败 err:" + err.Error(),
			"success": false,
		})
		return
	}
	// 返回成功响应
	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "提交成功",
		"success": true,
	})
	return
}

// QueryCommittedCC 查询链码提交情况
func QueryCommittedCC(c *gin.Context) {
	// 获取参数
	channelId := c.Query("channelId")
	orgName := c.Query("orgName")
	// 查询
	res, err := sdk.App.QueryCommittedCC(channelId, orgName)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "查询失败 err:" + err.Error(),
			"success": false,
		})
		return
	}
	// 返回成功响应
	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "查询成功",
		"data":    res,
		"success": true,
	})
	return
}

type CreatChannelForm struct {
	ChannelId      string `json:"channel_id"`
	ChannelCfgPath string `json:"channel_cfg_path"`
}

// CreatChannel 创建通道 POST
func CreatChannel(c *gin.Context) {
	// 解析信息
	data, err := c.GetRawData()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "获取消息失败",
			"success": false,
		})
		return
	}
	form := &CreatChannelForm{}
	err = json.Unmarshal(data, form)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "序列化 err:" + err.Error(),
			"success": false,
		})
		return
	}
	// 创建通道
	err = sdk.App.CreatChannel(form.ChannelId, form.ChannelCfgPath)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "创建失败 err:" + err.Error(),
			"success": false,
		})
		return
	}
	// 返回成功响应
	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "创建成功",
		"success": true,
	})
	return
}

type PeerJoinChannelForm struct {
	ChannelId string `json:"channel_id"`
	OrgName   string `json:"org_name"`
	PeerURL   string `json:"peer_url"`
}

// PeerJoinChannel 节点加入通道 POST
func PeerJoinChannel(c *gin.Context) {
	// 解析信息
	data, err := c.GetRawData()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "获取消息失败",
			"success": false,
		})
		return
	}
	form := &PeerJoinChannelForm{}
	err = json.Unmarshal(data, form)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "序列化 err:" + err.Error(),
			"success": false,
		})
		return
	}
	// 加入通道
	err = sdk.App.PeerJoinChannel(form.ChannelId, form.OrgName, form.PeerURL)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "节点" + form.PeerURL + "加入通道失败 err:" + err.Error(),
			"success": false,
		})
		return
	}
	// 返回成功响应
	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "加入成功",
		"success": true,
	})
	return
}
